package com.cskaoyan.demo6.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
@Aspect
public class ResultAspect {
    @Pointcut("execution(* com.cskaoyan.demo6.service.UserServiceImpl.divide(..))")
    public void pt(){}

    //前置通知
    @Before("pt()")
    public void beforeAdvice(JoinPoint joinPoint){
        Object target = joinPoint.getTarget();
        //代理类对象
        Object proxy= joinPoint.getThis();
        String methodName = joinPoint.getSignature().getName();
        //参数
        Object[] args = joinPoint.getArgs();
        System.out.println(target + ":" + methodName + ":" + Arrays.toString(args));
        System.out.println("这是一个前置通知");
    }
    //后置通知: 有点像finally
    @After("pt()")
    public void afterAdvice(){
        System.out.println("这是一个后置通知");
    }
    //环绕通知
    //1.返回结果必须要有返回值不可以是void，否则会把原来业务方法的执行结果丢失
    //2.必须要有一个形参ProceedingJoinPoint
    @Around("pt()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("这是环绕通知前");
        //相当于依然是对于原业务方法方法的封装调用
        Object proceed = joinPoint.proceed();
        System.out.println("这是环绕通知后");
        return proceed;
    }
    //返回结果
    @AfterReturning(value = "pt()",returning = "result")
    public void afterReturningAdvice(JoinPoint joinPoint,Object result){
        Object target = joinPoint.getTarget();
        String methodName = joinPoint.getSignature().getName();
        System.out.println(target + ":" + methodName + ":" + result);
        System.out.println("接收结果通知："+ result);
    }
    //异常通知：发生异常的时候会调用
    @AfterThrowing(value = "pt()",throwing = "e")
    public void expAdvice(Exception e){
        System.out.println("异常通知：" + e);
    }
}
